//
//  UIImage+averageColor.m
//  OpenCVDemo
//
//  Created by CuiPanJun on 15/8/31.
//  Copyright (c) 2015年 CuiPanJun. All rights reserved.
//

#import "UIImage+averageColor.h"


#define Mask8(x) ( (x) & 0xFF )
#define R(x) ( Mask8(x) )
#define G(x) ( Mask8(x >> 8 ) )
#define B(x) ( Mask8(x >> 16) )

@implementation UIImage (averageColor)

- (UIColor *)averageColor{
    CGRect imageBounds = CGRectMake(0, 0, self.size.width, self.size.height);
    return [self averageColorInRect:imageBounds];
}

- (UIColor *)averageColorInRect:(CGRect)cropRect{
    
    CGSize imageSize = self.size;
    CGRect imageBounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
    
    CGFloat x = CGRectGetMinX(cropRect);
    CGFloat y = CGRectGetMinY(cropRect);
    CGFloat w = CGRectGetWidth(cropRect);
    CGFloat h = CGRectGetHeight(cropRect);
    
    CGRect convertedRect = CGRectMake(x, y, w, h);
    
    CGRect resultImageRect = CGRectZero;
    
    if(!CGRectIntersectsRect(imageBounds, convertedRect)){
        return nil;
    }else{
        //resultImageRect = CGRectIntersection(imageBounds, convertedRect);
        
        CGFloat maxX = x + w;
        CGFloat maxY = y + h;
        
        if (x < 0) {
            x = 0;
        }
        
        if (y < 0) {
            y = 0;
        }
        
        if (maxX > imageSize.width) {
            maxX = imageSize.width;
        }
        
        if (maxY > imageSize.height) {
            maxY = imageSize.height;
        }
        
        resultImageRect = CGRectMake(x, y, maxX - x, maxY - y);
    }
    
    // 1.
    CGImageRef imageRef = self.CGImage;
    CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, resultImageRect);

    NSUInteger width = CGRectGetWidth(resultImageRect);
    NSUInteger height = CGRectGetHeight(resultImageRect);
    
    // 2.
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    
    UInt32 * pixels;
    pixels = (UInt32 *) calloc(height * width, sizeof(UInt32));
    
    // 3.
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    
    // 4.
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), subImageRef);
    
    // 5. Cleanup
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    
    CGFloat redSum = 0.0f;
    CGFloat greenSum = 0.0f;
    CGFloat blueSum = 0.0f;
    
    // 2.
    UInt32 * currentPixel = pixels;
    for (NSUInteger j = 0; j < height; j++) {
        for (NSUInteger i = 0; i < width; i++) {
            // 3.
            UInt32 color = *currentPixel;
            
            redSum += R(color);
            greenSum += G(color);
            blueSum += B(color);
            
            // 4.
            currentPixel++;
        }
    }
    
    free(pixels);
    
    long long totalPixelCount = width*height;
    CGFloat redAvg = (CGFloat)redSum/totalPixelCount;
    CGFloat greenAvg = (CGFloat)greenSum/totalPixelCount;
    CGFloat blueAvg = (CGFloat)blueSum/totalPixelCount;
    
    UIColor *avgColor = [UIColor colorWithRed:redAvg/255.0f green:greenAvg/255.0f blue:blueAvg/255.0f alpha:1.0f];
    return avgColor;
}

@end
